home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / comm / net / MailQueue371.lha / MailQueue / MailQueue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-24  |  13.4 KB  |  517 lines

  1. /*
  2. Auto:        sc <file>
  3. Auto:        Protect <file> ADD p
  4. */
  5.  
  6.  
  7. /* $Revision Header built automatically *************** (do not edit) ************
  8. **
  9. ** © Copyright by GuntherSoft
  10. **
  11. ** File             : SnakeSYS:CPrgs/MailQueue/MailQueue.c
  12. ** Created on       : Freitag, 13.01.95 17:12:27
  13. ** Created by       : Kai Iske
  14. ** Current revision : V37.1
  15. **
  16. **
  17. ** Purpose
  18. ** -------
  19. **     Watches your SMTP spool directory for the number of
  20. **     messages queued.
  21. **
  22. ** Revision V37.1
  23. ** --------------
  24. ** created on Sonntag, 22.01.95 03:25:27  by  Greg Patterson.   LogMessage :
  25. **  -*-  changed on Montag, 23.01.95 20:38:31  by  Kai Iske.   LogMessage :
  26. **   - Added new ONLYWB option, whichs causes the program
  27. **     to only open it`s window, on Workbench
  28. **  -*-  changed on Montag, 23.01.95 19:22:49  by  Kai Iske.   LogMessage :
  29. **   - MailQueue wasn`t really pure, as it used to set up LibBases
  30. **     as globals (well, technically wasn`t pure ;)). Changed.
  31. **     (Reported by : WShell users)
  32. **  -*-  changed on Sonntag, 22.01.95 23:37:04  by  Kai Iske.   LogMessage :
  33. **   - Whoops, wrong version string contained in executable ;)
  34. **  -*-  created on Sonntag, 22.01.95 03:25:27  by  Greg Patterson.   LogMessage :
  35. **   - Added ZEROCLOSE option to hide the Queue window when no messages are
  36. **     queued.
  37. **
  38. ** Revision V37.0
  39. ** --------------
  40. ** created on Freitag, 13.01.95 17:12:27  by  Kai Iske.   LogMessage :
  41. **     --- Initial release ---
  42. **
  43. *********************************************************************************/
  44. #define REVISION "37.1"
  45. #define REVDATE  "23.01.95"
  46. #define REVTIME  "20:38:31"
  47. #define AUTHOR   "Kai Iske"
  48. #define VERNUM   37
  49. #define REVNUM   1
  50.  
  51.  
  52.  
  53. #include    <stdlib.h>
  54. #include    <stdio.h>
  55. #include    <string.h>
  56. #include    <stdarg.h>
  57. #include    <exec/types.h>
  58. #include    <exec/memory.h>
  59. #include    <exec/execbase.h>
  60. #include    <proto/exec.h>
  61. #include    <proto/dos.h>
  62. #include    <proto/intuition.h>
  63. #include    <proto/netsupport.h>
  64. #include    <dos/dos.h>
  65. #include    <dos/dosextens.h>
  66. #include    <dos/notify.h>
  67. #include    <dos/exall.h>
  68. #include    <intuition/intuition.h>
  69.  
  70.  
  71.  
  72. /**********************************************************************/
  73. /*                           Version String                           */
  74. /**********************************************************************/
  75. static    const    char    Ver[]        = "$VER: MailQueue "REVISION" ("REVDATE")\0";
  76.  
  77.  
  78.  
  79.  
  80. /**********************************************************************/
  81. /*                              Template                              */
  82. /**********************************************************************/
  83. static    const    char    Template[]    = "WinX/N,WinY/N,OPENNOW/S,ZEROCLOSE/S,ONLYWB/S";
  84. enum{WINX_ARG, WINY_ARG, OPENNOW_ARG, ZEROCLOSE_ARG, ONLYWB_ARG, LAST_ARG};
  85.  
  86.  
  87.  
  88. /**********************************************************************/
  89. /*                        Our notify structure                        */
  90. /**********************************************************************/
  91. struct    NotifyNode
  92. {
  93.     struct    Node        Link;
  94.     struct    NotifyRequest    Notify;
  95.     char            Name[258];
  96. };
  97.  
  98.  
  99.  
  100.  
  101.  
  102. /**********************************************************************/
  103. /*                             Prototypes                             */
  104. /**********************************************************************/
  105. static    LONG    ScanDir(char *DirName, struct List *NotifyList, ULONG NotifySig, struct ExAllControl *EAC, struct ExAllData *EAB, struct DosLibrary *DOSBase);
  106. static    void    __stdargs SPrintF(STRPTR buffer, STRPTR formatString,...);
  107.  
  108.  
  109.  
  110.  
  111.  
  112. /**********************************************************************/
  113. /*                       This is the main stuff                       */
  114. /**********************************************************************/
  115. ULONG __saveds MailQueue(void)
  116. {
  117.     struct    ExecBase        *SysBase    = *((struct ExecBase **)0x4L);
  118.     struct    DosLibrary        *DOSBase;
  119.     struct    IntuitionBase        *IntuitionBase;
  120.     struct    NetSupportLibrary    *NetSupportBase;
  121.     struct    Process            *MyProc        = (struct Process *)SysBase->ThisTask;
  122.     struct    RDArgs            *RDArgs;
  123.     struct    ExAllControl        *EAC;
  124.     struct    ExAllData        *EAB;
  125.     LONG                NotifySig;
  126.     APTR                *Args;
  127.     ULONG                NotifyMask,
  128.                     MySig;
  129.     BOOL                Error        = TRUE;
  130.  
  131.  
  132.         // Ignore startup from WB
  133.  
  134.     if(!(MyProc->pr_CLI))
  135.     {
  136.         struct    Message *MyMsg;
  137.  
  138.         WaitPort(&MyProc->pr_MsgPort);
  139.         MyMsg = GetMsg(&MyProc->pr_MsgPort);
  140.         Disable();
  141.         ReplyMsg(MyMsg);
  142.         return(10);
  143.     }
  144.  
  145.         // Do the wild thing
  146.  
  147.     if((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  148.     {
  149.         if((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
  150.         {
  151.             if((NetSupportBase = (struct NetSupportLibrary *)OpenLibrary("netsupport.library", 1)))
  152.             {
  153.                 if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  154.                 {
  155.                     if((EAB = AllocVec(sizeof(struct ExAllData) * 16, MEMF_CLEAR)))
  156.                     {
  157.                         if((Args = AllocVec(LAST_ARG * sizeof(ULONG), MEMF_CLEAR)))
  158.                         {
  159.                             char    *Entry;
  160.  
  161.                             Entry    = GetConfig(NULL, "SMTPSPOOLDIR", "SMTPSPOOLDIR", "");
  162.  
  163.                             if(Entry && strlen(Entry))
  164.                             {
  165.                                 if((RDArgs = ReadArgs((char *)Template, (LONG *)Args, NULL)))
  166.                                 {
  167.                                     if((NotifySig = AllocSignal(-1)) != -1)
  168.                                     {
  169.                                         struct    List        NotifyList;
  170.                                         struct    NotifyRequest    DirNotify;
  171.                                         struct    NotifyNode    *Notify;
  172.                                         struct    Window        *NotifyWindow    = NULL;
  173.                                         ULONG            NotifyWinSig    = 0,
  174.                                                     WinLeft        = 0,
  175.                                                     WinTop        = 0;
  176.                                         char            WinTitle[80];
  177.                                         BOOL            Initial        = TRUE,
  178.                                                     ZeroClose    = TRUE,
  179.                                                     OnlyWB        = FALSE;
  180.  
  181.                                             // Get arguments
  182.  
  183.                                         if(Args[WINX_ARG])
  184.                                             WinLeft        = *((ULONG *)Args[WINX_ARG]);
  185.  
  186.                                         if(Args[WINY_ARG])
  187.                                             WinTop        = *((ULONG *)Args[WINY_ARG]);
  188.  
  189.                                         if(!Args[OPENNOW_ARG])
  190.                                             Initial        = FALSE;
  191.  
  192.                                         if(!Args[ZEROCLOSE_ARG])
  193.                                             ZeroClose    = FALSE;
  194.  
  195.                                         if(Args[ONLYWB_ARG])
  196.                                             OnlyWB        = TRUE;
  197.  
  198.  
  199.                                             // Set up list of notification requests
  200.  
  201.                                         NewList(&NotifyList);
  202.  
  203.                                             // Init notification for Directory
  204.                                             // and cause initial notification
  205.  
  206.                                         DirNotify.nr_Name                = Entry;
  207.                                         DirNotify.nr_Flags                = NRF_SEND_SIGNAL|NRF_NOTIFY_INITIAL;
  208.                                         DirNotify.nr_stuff.nr_Signal.nr_Task        = MyProc;
  209.                                         DirNotify.nr_stuff.nr_Signal.nr_SignalNum    = NotifySig;
  210.  
  211.                                             // Do it
  212.  
  213.                                         if(StartNotify(&DirNotify))
  214.                                         {
  215.                                             Error        = FALSE;
  216.  
  217.                                                 // Get Mask for Notification Signal
  218.  
  219.                                             NotifyMask    = 1 << NotifySig;
  220.  
  221.                                             for(;;)
  222.                                             {
  223.                                                 MySig    = Wait(SIGBREAKF_CTRL_C|NotifyMask|NotifyWinSig);
  224.  
  225.                                                     // Quit now
  226.  
  227.                                                 if(MySig & SIGBREAKF_CTRL_C)
  228.                                                     break;
  229.  
  230.                                                     // Anything has changed within the dir
  231.  
  232.                                                 if(MySig & NotifyMask)
  233.                                                 {
  234.                                                     LONG            Number;
  235.  
  236.                                                         // Rescan directory and set up new
  237.                                                         // notifications for files within the dir
  238.                                                         // Create appropriate Window title
  239.  
  240.                                                     if((Number = ScanDir(Entry, &NotifyList, NotifySig, EAC, EAB, DOSBase)) != -1)
  241.                                                     {
  242.                                                         if(ZeroClose && !Number && NotifyWindow)
  243.                                                         {
  244.                                                             CloseWindow(NotifyWindow);
  245.                                                             NotifyWindow    = NULL;
  246.                                                             NotifyWinSig    = 0;
  247.                                                         }
  248.                                                         else
  249.                                                             SPrintF(WinTitle, "%ld Message(s) queued", Number);
  250.                                                     }
  251.                                                     else
  252.                                                         strcpy(WinTitle, "Couldn`t get information");
  253.  
  254.                                                         // Update window?
  255.  
  256.                                                     if(NotifyWindow || Number > 0 || Initial)
  257.                                                     {
  258.                                                             // Window not opened yet?
  259.  
  260.                                                         if(!NotifyWindow)
  261.                                                         {
  262.                                                             struct    Screen    *WB    = LockPubScreen((OnlyWB ? "Workbench" : NULL));
  263.  
  264.                                                                 // Open window
  265.  
  266.                                                             if(WB)
  267.                                                             {
  268.                                                                 if((NotifyWindow = OpenWindowTags(NULL,
  269.                                                                     WA_Left,    WinLeft,
  270.                                                                     WA_Top,        WinTop,
  271.                                                                     WA_Width,    (WB->RastPort.TxWidth * 40),
  272.                                                                     WA_Height,    (WB->RastPort.TxHeight + 3),
  273.                                                                     WA_Flags,    WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET,
  274.                                                                     WA_IDCMP,    IDCMP_CHANGEWINDOW|IDCMP_CLOSEWINDOW,
  275.                                                                     WA_PubScreen,    WB,
  276.                                                                     WA_Title,    WinTitle,
  277.                                                                 TAG_DONE)))
  278.                                                                     NotifyWinSig    = 1 << NotifyWindow->UserPort->mp_SigBit;
  279.  
  280.                                                                 UnlockPubScreen(NULL, WB);
  281.                                                             }
  282.                                                         }
  283.                                                         else
  284.                                                             SetWindowTitles(NotifyWindow, WinTitle, (char *)~0);
  285.  
  286.                                                         Initial = FALSE;
  287.                                                     }
  288.                                                 }
  289.  
  290.                                                     // Signal from window?
  291.  
  292.                                                 if(MySig & NotifyWinSig)
  293.                                                 {
  294.                                                     struct    IntuiMessage    *Msg;
  295.                                                     BOOL            Close    = FALSE;
  296.  
  297.                                                     while((Msg = (struct IntuiMessage *)GetMsg(NotifyWindow->UserPort)))
  298.                                                     {
  299.                                                         if(Msg->Class == IDCMP_CLOSEWINDOW)
  300.                                                             Close    = TRUE;
  301.                                                         else if(Msg->Class == IDCMP_CHANGEWINDOW)
  302.                                                         {
  303.                                                             WinLeft = NotifyWindow->LeftEdge;
  304.                                                             WinTop    = NotifyWindow->TopEdge;
  305.                                                         }
  306.  
  307.                                                         ReplyMsg((struct Message *)Msg);
  308.                                                     }
  309.  
  310.                                                     if(Close)
  311.                                                     {
  312.                                                         CloseWindow(NotifyWindow);
  313.                                                         NotifyWindow    = NULL;
  314.                                                         NotifyWinSig    = 0;
  315.                                                     }
  316.                                                 }
  317.                                             }
  318.  
  319.                                                 // Close window
  320.  
  321.                                             if(NotifyWindow)
  322.                                                 CloseWindow(NotifyWindow);
  323.  
  324.                                                 // Kill Notifications
  325.  
  326.                                             while((Notify = (struct NotifyNode *)RemHead(&NotifyList)))
  327.                                             {
  328.                                                 EndNotify(&Notify->Notify);
  329.                                                 FreeVec(Notify);
  330.                                             }
  331.  
  332.                                                 // End Dir Notification
  333.  
  334.                                             EndNotify(&DirNotify);
  335.                                         }
  336.                                         else
  337.                                             FPuts(Output(), "MailQueue : Couldn`t launch Notification\n");
  338.  
  339.                                         FreeSignal(NotifySig);
  340.                                     }
  341.                                     else
  342.                                         FPuts(Output(), "MailQueue : Couldn`t allocate Signal\n");
  343.  
  344.                                     FreeArgs(RDArgs);
  345.                                 }
  346.                                 else
  347.                                     PrintFault(IoErr(), "MailQueue ");
  348.                             }
  349.                             else
  350.                                 FPuts(Output(), "MailQueue : SMTPSPOOLDIR settings not found\n");
  351.  
  352.                             FreeVec(Args);
  353.                         }
  354.                         else
  355.                             PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  356.  
  357.                         FreeVec(EAB);
  358.                     }
  359.                     else
  360.                         PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  361.  
  362.                     FreeDosObject(DOS_EXALLCONTROL, EAC);
  363.                 }
  364.                 else
  365.                     PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  366.  
  367.                 CloseLibrary((struct Library *)NetSupportBase);
  368.             }
  369.             else
  370.                 FPuts(Output(), "MailQueue : Couldn`t open netsupport.library\n");
  371.  
  372.             CloseLibrary((struct Library *)IntuitionBase);
  373.         }
  374.         else
  375.             FPuts(Output(), "MailQueue : Couldn`t open intuition.library\n");
  376.  
  377.         CloseLibrary((struct Library *)DOSBase);
  378.     }
  379.  
  380.     if(Error)
  381.         return(10);
  382.     else
  383.         return(0);
  384. }
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393. /**********************************************************************/
  394. /*            Scan the directory for the "D.#?" files                 */
  395. /**********************************************************************/
  396. static LONG ScanDir(char *DirName, struct List *NotifyList, ULONG NotifySig, struct ExAllControl *EAC, struct ExAllData *EAB, struct DosLibrary *DOSBase)
  397. {
  398.     struct    NotifyNode    *Notify;
  399.     struct    ExAllData    *EAD;
  400.     BPTR            DirLock;
  401.     char            Pattern[32];
  402.     LONG            Number        = -1;
  403.     BOOL            Scanning;
  404.  
  405.  
  406.         // First stop all pending notifications
  407.  
  408.     while((Notify = (struct NotifyNode *)RemHead(NotifyList)))
  409.     {
  410.         EndNotify(&Notify->Notify);
  411.         FreeVec(Notify);
  412.     }
  413.  
  414.         // Create pattern for files (Message files start with "D.")
  415.  
  416.     if(ParsePatternNoCase("D.#?", Pattern, 32) != -1)
  417.     {
  418.             // Scan directory
  419.  
  420.         if((DirLock = Lock(DirName, ACCESS_READ)))
  421.         {
  422.             EAC->eac_LastKey    = 0;
  423.             EAC->eac_MatchString    = Pattern;
  424.             EAC->eac_MatchFunc    = 0;
  425.  
  426.             Number        = 0;
  427.  
  428.             do
  429.             {
  430.                 Scanning    = ExAll(DirLock, EAB, (16 * sizeof(struct ExAllControl)), ED_NAME, EAC);
  431.  
  432.                 if(!Scanning && (IoErr() != ERROR_NO_MORE_ENTRIES))
  433.                     Number    = -1;
  434.  
  435.                 if(EAC->eac_Entries == 0)
  436.                     Scanning    = FALSE;
  437.                 else if(Number != -1)
  438.                 {
  439.                     EAD    = EAB;
  440.  
  441.                     do
  442.                     {
  443.                             // Create new notification for file found
  444.  
  445.                         if((Notify = AllocVec(sizeof(struct NotifyNode), MEMF_CLEAR)))
  446.                         {
  447.                             Number++;
  448.  
  449.                                 // Create filename with path
  450.  
  451.                             NameFromLock(DirLock, Notify->Name, 256);
  452.                             AddPart(Notify->Name, EAD->ed_Name, 256);
  453.  
  454.                                 // Set up notification on file
  455.  
  456.                             Notify->Notify.nr_Name                = Notify->Name;
  457.                             Notify->Notify.nr_Flags                = NRF_SEND_SIGNAL;
  458.                             Notify->Notify.nr_stuff.nr_Signal.nr_Task    = FindTask(NULL);
  459.                             Notify->Notify.nr_stuff.nr_Signal.nr_SignalNum    = NotifySig;
  460.  
  461.                                 // Start notification
  462.  
  463.                             if(!StartNotify(&Notify->Notify))
  464.                             {
  465.                                     // Error -> Abort and free memory of node
  466.  
  467.                                 Number    = -1;
  468.                                 FreeVec(Notify);
  469.                                 break;
  470.                             }
  471.                             else
  472.                             {
  473.                                     // Add node to list
  474.  
  475.                                 AddTail(NotifyList, (struct Node *)Notify);
  476.                             }
  477.                         }
  478.                         else
  479.                             Number    = -1;
  480.  
  481.                         EAD    = EAD->ed_Next;
  482.                     } while(EAD && Number != -1);
  483.                 }
  484.             } while(Scanning && Number != -1);
  485.  
  486.             UnLock(DirLock);
  487.         }
  488.     }
  489.  
  490.         // Error?!?! Kill requests
  491.  
  492.     if(Number == -1)
  493.     {
  494.         while((Notify = (struct NotifyNode *)RemHead(NotifyList)))
  495.         {
  496.             EndNotify(&Notify->Notify);
  497.             FreeVec(Notify);
  498.         }
  499.     }
  500.  
  501.     return(Number);
  502. }
  503.  
  504.  
  505.  
  506.  
  507. /**********************************************************************/
  508. /*               My special sprintf                  */
  509. /**********************************************************************/
  510. static void __stdargs SPrintF(STRPTR buffer, STRPTR formatString,...)
  511. {
  512.     va_list varArgs;
  513.     va_start(varArgs,formatString);
  514.     RawDoFmt(formatString,varArgs,(void (*)())(void (*))"\x16\xC0\x4E\x75",buffer);
  515.     va_end(varArgs);
  516. }
  517.